const dayjs = require('dayjs');
/**
 * 研发项目基础文件管理模块
 * 包含通用的文件上传、下载、预览、删除等功能，供资源和文档管理模块继承使用
 */

// 引入辅助工具
const cloudHelper = require('./helpers/cloud_helper.js');
const pageHelper = require('./helpers/page_helper.js');
const timeHelper = require('./helpers/time_helper.js');

/**
 * 基础文件管理器类
 * 提供通用的文件操作功能
 */
class BaseFileManager {
  /**
   * 构造函数
   * @param {Object} page - 页面实例
   * @param {Object} options - 配置选项
   */
  constructor(page, options = {}) {
    this.page = page;
    this.options = options;
    this.cacheTime = options.cacheTime || 5 * 60 * 1000; // 默认缓存5分钟
    this.cache = {};
  }

  /**
   * 上传文件
   * @param {Object} file - 文件信息
   * @param {string} file.projectId - 项目ID
   * @param {string} file.type - 文件类型
   * @param {string} file.name - 文件名称
   * @param {string} file.fileName - 原始文件名
   * @param {string} file.tempFilePath - 临时文件路径
   * @param {number} file.size - 文件大小
   * @param {string} cloudDir - 云存储目录
   * @param {Object} extraData - 额外数据
   * @param {string} cloudFunction - 云函数名称
   * @returns {Promise<Object>} 上传结果
   */
  async uploadFile(file, cloudDir, extraData = {}, cloudFunction) {
    if (!file || !file.projectId || !file.type || !file.tempFilePath) {
      throw new Error('文件信息不完整');
    }
    
    try {
      // 构建云存储路径
      const cloudPath = `project/${file.projectId}/${cloudDir}/${timeHelper.time('YMDHms')}_${file.fileName}`;
      
      // 上传文件到云存储
      const fileResult = await cloudHelper.uploadFile(file.tempFilePath, cloudPath, null, file.type);
      
      // 构建提交到数据库的参数
      const params = {
        projectId: file.projectId,
        type: file.type,
        name: file.name || file.fileName,
        fileName: file.fileName,
        fileId: fileResult.fileID,
        size: fileResult.size,
        ...extraData
      };
      
      // 调用云函数，将文件信息写入数据库
      const result = await cloudHelper.callCloud(cloudFunction, params, {});
      
      // 清除缓存
      this.clearCache(file.projectId);
      
      return result;
    } catch (error) {
      console.error('上传文件失败', error);
      pageHelper.showError('上传失败: ' + error.message);
      throw error;
    }
  }

  /**
   * 预览文件
   * @param {Object} file - 文件对象
   * @param {string} file.fileId - 文件ID
   * @param {string} file.name - 文件名称
   * @returns {Promise<void>}
   */
  async viewFile(file) {
    if (!file || !file.fileId) {
      pageHelper.showError('文件不存在');
      return;
    }

    try {
      // 获取文件临时路径
      const tempFilePath = await cloudHelper.getTempFileURL(file.fileId);
      
      // 打开文件预览
      wx.openDocument({
        filePath: tempFilePath,
        showMenu: true,
        success: () => {
          console.log('打开文档成功');
        },
        fail: (error) => {
          console.error('打开文档失败', error);
          pageHelper.showError('打开文档失败: ' + error.errMsg);
        }
      });
    } catch (error) {
      console.error('预览文件失败', error);
      pageHelper.showError('预览文件失败: ' + error.message);
    }
  }

  /**
   * 下载文件
   * @param {Object} file - 文件对象
   * @param {string} file.fileId - 文件ID
   * @param {string} file.name - 文件名称
   * @returns {Promise<void>}
   */
  async downloadFile(file) {
    if (!file || !file.fileId) {
      pageHelper.showError('文件不存在');
      return;
    }

    try {
      await cloudHelper.downloadFile(file.fileId, file.name);
      pageHelper.showSuccToast('下载成功');
    } catch (error) {
      console.error('下载文件失败', error);
      pageHelper.showError('下载文件失败: ' + error.message);
    }
  }

  /**
   * 批量下载文件
   * @param {Array} files - 文件列表
   * @param {string} fileIdKey - 文件ID属性名
   * @param {string} fileNameKey - 文件名称属性名
   * @returns {Promise<void>}
   */
  async batchDownloadFiles(files, fileIdKey, fileNameKey) {
    if (!files || !Array.isArray(files) || files.length === 0) {
      pageHelper.showError('没有可下载的文件');
      return;
    }

    try {
      // 创建进度显示
      pageHelper.showLoading('准备下载...');
      
      // 依次下载文件
      for (let i = 0; i < files.length; i++) {
        const file = files[i];
        const fileId = file[fileIdKey];
        const fileName = file[fileNameKey];
        
        if (!fileId) continue;
        
        pageHelper.showLoading(`下载文件 ${i + 1}/${files.length}`);
        await cloudHelper.downloadFile(fileId, fileName);
      }
      
      pageHelper.hideLoading();
      pageHelper.showSuccToast('批量下载完成');
    } catch (error) {
      pageHelper.hideLoading();
      console.error('批量下载文件失败', error);
      pageHelper.showError('批量下载失败: ' + error.message);
    }
  }

  /**
   * 删除文件
   * @param {string} fileId - 文件ID
   * @param {string} projectId - 项目ID
   * @param {string} cloudFunction - 云函数名称
   * @param {Object} extraParams - 额外参数
   * @returns {Promise<boolean>} 是否删除成功
   */
  async deleteFile(fileId, projectId, cloudFunction, extraParams = {}) {
    if (!fileId) return false;
    
    try {
      const params = {
        ...extraParams,
        fileId: fileId
      };
      
      await cloudHelper.callCloud(cloudFunction, params, {});
      
      // 清除缓存
      if (projectId) {
        this.clearCache(projectId);
      }
      
      return true;
    } catch (error) {
      console.error('删除文件失败', error);
      pageHelper.showError('删除文件失败: ' + error.message);
      return false;
    }
  }

  /**
   * 获取缓存数据
   * @param {string} key - 缓存键
   * @returns {*} 缓存数据，如果不存在或已过期则返回null
   */
  getCache(key) {
    if (!key || !this.cache[key]) return null;
    
    const cacheItem = this.cache[key];
    if (dayjs().valueOf() - cacheItem.time > this.cacheTime) {
      // 缓存已过期
      delete this.cache[key];
      return null;
    }
    
    return cacheItem.data;
  }

  /**
   * 设置缓存数据
   * @param {string} key - 缓存键
   * @param {*} data - 缓存数据
   */
  setCache(key, data) {
    if (!key) return;
    
    this.cache[key] = {
      time: dayjs().valueOf(),
      data: data
    };
  }

  /**
   * 清除指定项目的缓存
   * @param {string} projectId - 项目ID
   */
  clearCache(projectId) {
    if (!projectId) return;
    
    // 清除所有包含该项目ID的缓存
    Object.keys(this.cache).forEach(key => {
      if (key.includes(projectId)) {
        delete this.cache[key];
      }
    });
  }

  /**
   * 清除所有缓存
   */
  clearAllCache() {
    this.cache = {};
  }

  /**
   * 格式化文件大小
   * @param {number} size - 文件大小(字节)
   * @returns {string} 格式化后的文件大小
   */
  formatFileSize(size) {
    if (size < 1024) {
      return size + 'B';
    } else if (size < 1024 * 1024) {
      return (size / 1024).toFixed(2) + 'KB';
    } else if (size < 1024 * 1024 * 1024) {
      return (size / (1024 * 1024)).toFixed(2) + 'MB';
    } else {
      return (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB';
    }
  }
}

module.exports = BaseFileManager; 